/*
 * @file     g_chgrin.c
 * @brief    This file provides all the CHGR_IN firmware functions
 *
 * Change Logs:
 * Date            Author             Version        Notes
 * 2021-05-25      dengzhiqian        V1.0.0         the first version
 * 2021-03-17      dengzhiqian        V1.0.1         add chgrin calib func
 */

#include "g_chgrin.h"

static uint8_t otpchgrvcc = 0xff;
/**
 * @method G_CHGR_Event_Detect_En
 * @brief  Event detection enable. This bit must be enabled before enabling can be interrupted. POWER_KEY is always enabled
 * @param  Chgr_Event: This parameter can be
 *         CHGR_EVENT0 : enent0 ~ event9 enable or disable
 *         CHGR_EVENT1 : enent10 ~ event11 enable or disable
 *         CHGR_EVENT_ALL : event all enable or disable
 * @param  NewState: new state of the CHGR_IN interrupt enable
 *         This parameter can be: ENABLE or DISABLE
 * @retval None
 */
void G_CHGR_Event_Detect_En(CHGR_Event_DecEnDef Chgr_Event,G_FunctionalState NewState)
{
    _ASSERT(IS_DECTECT_EN_SELECT(Chgr_Event));

    if(Chgr_Event == CHGR_EVENT0)
    {
        MSYSCTRL->CHGR_EVENT_IRQ.bit.EVENT0_EN = NewState;
    }
    else if(Chgr_Event == CHGR_EVENT1)
    {
        MSYSCTRL->CHGR_EVENT_IRQ.bit.EVENT1_EN = NewState;
    }
    else
    {
        MSYSCTRL->CHGR_EVENT_IRQ.bit.EVENT0_EN = NewState;
        MSYSCTRL->CHGR_EVENT_IRQ.bit.EVENT1_EN = NewState;
    }
}

/**
 * @method G_CHGR_Irq_En
 * @brief  Chgrin interrupt enable master switch
 * @param  NewState: new state of the CHGR_IN interrupt enable
 *         This parameter can be: ENABLE or DISABLE
 * @retval None
 */
void G_CHGR_Irq_En(G_FunctionalState NewState)
{
    _ASSERT(IS_FUNCTIONAL_STATE(NewState));

    MSYSCTRL->CHGR_EVENT_IRQ.bit.IE = NewState;
}

/**
 * @method G_CHGR_Event_En
 * @brief  CHGR_IN interrupt event enable
 * @param  Chgr_Event: To enable interrupt event
 *         This parameter can be:
 *         EVENT0_CHGR_STATE_VBAT_LV
 *         EVENT1_CHGR_STATE_RCH_EN
 *         EVENT2_CHGR_STATE_IND
 *         EVENT3_CHGR_STATE_ICHG
 *         EVENT4_CHGR_RESET
 *         EVENT5_CHGR_UVLO_OK_AON
 *         EVENT6_CHGR_PGOOD
 *         EVENT7_CHGR_DPPM_OV_CV
 *         EVENT8_CHGR_DPPM_OV_CC
 *         EVENT9_CHGR_CC_OV_CV
 *         EVENT10_CHGR_IN_DET_AON
 *         EVENT11_VBAT_OV_FLAG
 *         EVENT12_POWER_KEY
 *         EVENT_ALL
 * @param  NewState: new state of the CHGR_IN interrupt
 *         This parameter can be: ENABLE or DISABLE
 * @retval None
 */
void G_CHGR_Event_En(uint32_t Chgr_Event,G_FunctionalState NewState)
{
    _ASSERT(IS_FUNCTIONAL_STATE(NewState));
    _ASSERT(IS_CHGR_EVENT_SELECT(Chgr_Event));

    if(NewState)
    {
        MSYSCTRL->CHGR_EVENT_ICTRL.reg |= Chgr_Event;
    }
    else
    {
        MSYSCTRL->CHGR_EVENT_ICTRL.reg &= ~Chgr_Event;
    }
}


/**
 * @method G_CHARGE_CurSel
 * @brief  set charging current
 * @param  ChargCurtSel: charging current
 * @retval None
 */
void G_CHARGE_CurSel(CHARG_Current ChargCurtSel)
{
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);

    MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_ICHG_SET = ChargCurtSel;
}

/**
 * @method G_CHARGE_SystemPowerSelect
 * @brief  Configure chip power supply
 * @param  powerSource: The power to choose
 * @retval None
 */
void G_CHARGE_SystemPowerSelect(CHARG_SystemPowerSource powerSource)
{
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);

    MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_SHUTDOWN_SW = powerSource;
}


/**
 * @method CHGR_Interrupt_Type
 * @brief  CHGR_IN interrupt type select
 * @param  Chgr_Event: To enable interrupt event
 *         This parameter can be:
 *         EVENT0_CHGR_STATE_VBAT_LV
 *         EVENT1_CHGR_STATE_RCH_EN
 *         EVENT2_CHGR_STATE_IND
 *         EVENT3_CHGR_STATE_ICHG
 *         EVENT4_CHGR_RESET
 *         EVENT5_CHGR_UVLO_OK_AON
 *         EVENT6_CHGR_PGOOD
 *         EVENT7_CHGR_DPPM_OV_CV
 *         EVENT8_CHGR_DPPM_OV_CC
 *         EVENT9_CHGR_CC_OV_CV
 *         EVENT10_CHGR_IN_DET_AON
 *         EVENT11_VBAT_OV_FLAG
 *         EVENT12_POWER_KEY
 *         EVENT_ALL
 * @param  Irq_Type:
 *         This parameter can be:
 *         CHGR_LOW_LEVEL : low level trigger
 *         CHGR_HIGH_LEVEL : high level trigger
 * @retval None
 */
void G_CHGR_Event_Irq_Type(uint32_t Chgr_Event,CHGR_Event_IrqTypeDef Irq_Type)
{
    _ASSERT(IS_TYRE_SELECT(Irq_Type));
    _ASSERT(IS_CHGR_EVENT_SELECT(Chgr_Event));

    if(Irq_Type == CHGR_HIGH_LEVEL)
    {
        MSYSCTRL->CHGR_EVENT_ICTRL.reg |= (Chgr_Event << 16);
    }
    else
    {
        MSYSCTRL->CHGR_EVENT_ICTRL.reg &= ~(Chgr_Event << 16);
    }
}


/**
 * @method G_CHGR_Event_Clear_Irq
 * @brief  Clear chgr interrupt flag
 * @param  Chgr_Event: To enable interrupt event
 *         This parameter can be:
 *         EVENT0_CHGR_STATE_VBAT_LV
 *         EVENT1_CHGR_STATE_RCH_EN
 *         EVENT2_CHGR_STATE_IND
 *         EVENT3_CHGR_STATE_ICHG
 *         EVENT4_CHGR_RESET
 *         EVENT5_CHGR_UVLO_OK_AON
 *         EVENT6_CHGR_PGOOD
 *         EVENT7_CHGR_DPPM_OV_CV
 *         EVENT8_CHGR_DPPM_OV_CC
 *         EVENT9_CHGR_CC_OV_CV
 *         EVENT10_CHGR_IN_DET_AON
 *         EVENT11_VBAT_OV_FLAG
 *         EVENT12_POWER_KEY
 *         EVENT_ALL
 * @retval None
 */
void G_CHGR_Event_Clear_Irq(uint32_t Chgr_Event)
{
    _ASSERT(IS_CHGR_EVENT_SELECT(Chgr_Event));

    MSYSCTRL->CHGR_EVENT_IRQ.reg |= Chgr_Event;
}

/**
 * @method G_CHGR_Event_Get_Irq_State
 * @brief  get the event interrupt status
 * @param  None
 * @retval Bit 0~12 represents the interrupt state of event 0~12
 */
uint32_t G_CHGR_Event_Get_Irq_State(void)
{
    return (MSYSCTRL->CHGR_EVENT_IRQ.reg & EVENT_ALL);
}


/**
 * @method G_CHARGE_InsertDet
 * @brief  USB insertion detection
 * @param  None
 * @retval TRUE or FALSE
 */
G_Boolean G_CHARGE_InsertDet(void)
{
    //need event en 
    if(ANA_CHGR->STATE.bit.CHGR_IN_DET_AON)
    {
        return TRUE;
    }
    return FALSE;
}

/**
 * @method G_CHARGE_State
 * @brief  Charge status
 * @param  None
 * @retval TRUE or FALSE
 */
G_Boolean G_CHARGE_State(void)
{
    //need event en 
    if(ANA_CHGR->STATE.bit.CHGR_STATE_IND)
    {
        return TRUE;
    }
    return FALSE;
}

static uint8_t CHARGE_GetClibVol(uint8_t ChargOutVol)
{
    uint8_t xorbit = 0;
    uint8_t enable = 0;
    if(otpchgrvcc == 0xff)
    {
        G_OTP_Read(OTP_CHGRVCCADDR,&otpchgrvcc,OTP_CHGRVCCLEN);
        xorbit  = G_OTP_DataXOR(otpchgrvcc,4);
        enable = (otpchgrvcc >> 7) & 0x01;
    }

    if(enable && (xorbit == ((otpchgrvcc >> 6) & 0x01)))
    {
        otpchgrvcc &= 0x0f;
    }
    else
    {
        return ChargOutVol;
    }
        
    
    if(otpchgrvcc > OVERVOLTAGE_4200MV)
    {
        ChargOutVol += (otpchgrvcc - OVERVOLTAGE_4200MV);
        ChargOutVol = ChargOutVol > 0x0f ? 0x0f:ChargOutVol;
    }
    else
    {
        ChargOutVol -= (OVERVOLTAGE_4200MV - otpchgrvcc);
        ChargOutVol = ChargOutVol > 0x0f ? 0:ChargOutVol;
    }
    return ChargOutVol;
}

/**
  * @brief	Configure the charge cut-off voltage,
            the nomina value is 4.2V,and the step
            length is 53mV. The data width is 4 effective
            data bits.The register defaults is 8.
  * @param	ChargOutVol: Charge cut-off voltage
  * @retval 	none
  */
void G_CHARGE_CutOffVolSel(CHARG_OverVoltage ChargOutVol)
{
    uint8_t Calvol = 0;
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);
    
    Calvol = CHARGE_GetClibVol(ChargOutVol);
    MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_CVC = Calvol;
}

/**
    *@Brief configure recharge voltage,
            The nominal value is 4.1V in steps
            The length is 53mV. The data width is 4
            Data bits. The default value of the register is 8.
    *@Param chargoutvol: charging and recharging voltage
    *@Retval none
    */
void G_CHARGE_RechargeVolSel(CHARG_StartVoltage ChargOutVol)
{
    uint8_t Calvol = 0;
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);
    
    Calvol = CHARGE_GetClibVol(ChargOutVol);
    MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_RCHC = Calvol;
}

/**
    *@Brief configure the trickle charging mode when the lithium battery voltage is lower than 3V,
                Trickle charging mode starts from 10% and has 4 gradients
                The default value of the register is 0.
    *@Param Trickle_Gradient: trickle charge percentage
    *@Retval none
*/
void G_CHARGE_TrickleCurrent( CHARGE_TRICKLE_GRADIENT Trickle_Gradient )
{
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);
    
    MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_TCC = Trickle_Gradient;
}

/**
    *@Brief configure the trickle charging mode when charging is terminated,
                Trickle charging mode starts from 10% and has 4 gradients
                The default value of the register is 0.
    *@Param Trickle_Gradient: trickle charge percentage
    *@Retval none
*/

void G_CHARGE_TerminationCurrent( CHARGE_TRICKLE_GRADIENT Trickle_Gradient )
{
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);
    
    MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_TERMC = Trickle_Gradient;
}

/**
    *@Brief configure Force off charger bias
    *@Param 0: on; 1: off
    *@Retval none
*/
void G_CHARGE_ForceOffChargerBias(G_FunctionalState NewState)
{
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);
    
    if(NewState == ENABLE)
    {
        MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_SHUTDOWN_BIAS = 0;
    }
    else
    {
        MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_SHUTDOWN_BIAS = 1;
    }
}
/**
    *@Brief configure Force off charger CC & CV loop
    *@Param 0: on; 1: off
    *@Retval none
*/
void G_CHARGE_ForceOffChargerCCAndCV(G_FunctionalState NewState)
{
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);
    if(NewState == ENABLE)
    {
        MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_SHUTDOWN_CORE = 0;
    }
    else
    {
        MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_SHUTDOWN_CORE = 1;
    }
}
/**
    *@Brief configure Force off charger pass transistor
    *@Param 0: HVIN supplied by VBUS; 1: HVIN supplied by battery
    *@Retval none
*/
void G_CHARGE_ForceOffChargerPassTransistor(G_FunctionalState NewState)
{
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);
    
    MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_SHUTDOWN_SW = NewState;
}
/**
    *@Brief configure Charger CC mode force enable. 
                Only valid when chgr_force_core_on = 1 or charging is on-going
    *@Param 0: normal operation; 1: force on
    *@Retval none
*/
void G_CHARGE_ForceCCModeConfig(G_FunctionalState NewState)
{
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);
    
    MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_FORCE_CC = NewState;
}
/**
    *@Brief Force on charger CC & CV loop when charger is in standby mode. 
                Only valid when chgr_shutdown_core = 0
    *@Param 
    *@Retval none
*/
void G_CHARGE_ForceCCAndCVLoop(G_FunctionalState NewState)
{
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);
    
    MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_FORCE_CORE_ON = NewState;
}
/**
    *@Brief Charger CV mode force enable. 
                Only valid when chgr_force_core_on = 1 or charging is on-going
    *@Param 0: normal operation; 1: force on
    *@Retval none
*/
void G_CHARGE_ForceCVMode(G_FunctionalState NewState)
{
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);
    
    MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_FORCE_CV = NewState;
}
/**
    *@Brief Charger input sink current enable. 
        Used to wake up charger case and to be turned off upon the end of charging process.
    *@Param 0: enable; 1: disable
    *@Retval none
*/
void G_CHARGE_InputSinkCurrent(G_FunctionalState NewState)
{
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);
    
    MLPM->CHGR_CTRL.bit.RG_LPM_CHGR_INSC_ENB = NewState;
}

/**
    *@Brief Charger Force mode switch. 
        open or close Charger-force mode.
    *@Param 1: enable; 0: disable
    *@Retval none
*/
void G_CHARGE_ForceSwitch(G_FunctionalState NewState)
{
    G_LPM_AccessCode(ENABLE);
    G_LPM_RegisterClk(ENABLE);
    if(NewState == ENABLE)
    {
        G_CHARGE_ForceOffChargerBias(ENABLE);
        G_CHARGE_ForceOffChargerCCAndCV(ENABLE);
        G_CHARGE_ForceCCAndCVLoop(ENABLE);
    }
    else
    {
        G_CHARGE_ForceCCAndCVLoop(DISABLE);
        G_CHARGE_ForceOffChargerBias(DISABLE);
        G_CHARGE_ForceOffChargerCCAndCV(DISABLE);
        G_CHARGE_ForceOffChargerBias(ENABLE);
    }
}

/************************ (C) COPYRIGHT GKT *****END OF FILE****/
